import { t } from 'i18next'
import React from 'react'
import { CheckBox, Button } from '@kedacom/react-next'
import { StyledWrap } from './style'
import Alert from '@/components/Alert'

interface LabelCheckBoxProps {
	mainDesc: string
	subDesc: string
	list: ICheckBoxItem[]
	maxLimit?: number
	defaultValue?: string[]
}
interface ICheckBoxItem {
	text: string
	checked: 0 | 1
	value: string
	onChange: (val: 0 | 1) => void
	width?: number
	disabled?: boolean
	hide?: boolean
}
/*
组件的使用
这个是props中的list的数据
const commonSettings = [
	{
		text: t('邀请终端'),
		value: 'mt_add',
		checked: configInfo.mt_add,
		onChange: (val: 0 | 1) => {
			propsChange({ type: 'setMtAdd', payLoad: val })
		},
	},
	{
		text: t('呼叫全部离线'),
		value: 'mt_add_all',
		checked: configInfo.mt_add_all,
		onChange: (val: 0 | 1) => {
			propsChange({ type: 'setMtAddAll', payLoad: val })
		},
	},
	...
]

<LabelCheckBox
	mainDesc={t('在线终端快捷操作')}
	subDesc={t('勾选后会议控制界面会出现对应快捷操作，最多选7项')}
	list={terminalSettings}
	defaultValue={defaultValue}
	maxLimit={7}
></LabelCheckBox>

<LabelCheckBox
	mainDesc={t('选中常用功能')}
	subDesc={t('勾选后常用功能中会出现对应的功能，最多选15项')}
	list={commonSettings}
	defaultValue={defaultValue}
	maxLimit={15}
></LabelCheckBox>
*/
export default function LabelCheckBox({ mainDesc, subDesc, list, maxLimit, defaultValue }: LabelCheckBoxProps) {
	/*
	checkedCount 计算选中的有多少个

	# array.reduce()
	通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化。

	---------------------------------------------

	# 一、array.reduce(）的使用与技巧
		## 1.1、基本语法
			array.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)

			### 1.1.1、参数
				其中callback回调函数用于处理每个数组元素，最后返回一个累加值。
				accumulator：累加器，累加回调的返回值（或提供的初始值）。
				currentValue：当前元素。
				currentIndex（可选）：当前元素的索引。
				array（可选）：调用 reduce 的数组。
				initialValue（可选）：作为累加器的起始值。如果没有提供，array 的第一个元素将用作累加器的初始值，currentValue 将从 array 的第二个元素开始。 

			### 1.1.2、提供参数与行为       
				如果提供了 initialValue，累加器将被设置为这个值，currentValue 将被设置为数组的第一个元素。
				如果没有提供 initialValue，reduce 将从索引 1 开始遍历数组，
				并且数组的第一个元素将作为累加器的初始值，
				currentValue 将从数组的第二个元素开始。
				callback 函数被依次应用到每个数组元素上，直到所有元素都被处理完毕。
				reduce 方法最后返回累加器的最终值。
		## 1.2、返回值
			一个累加值，准确来说是一个累加器，因为不一定是返回一个数值，也可以是数组等其他数据结构，这个结构主要由initialValue决定，比如initialValue是[]，那么最后的累加器就是一个数组，根据回调函数决定往数组里添加什么内容。

		## 1.3、使用技巧
			array.reduce(）是用于将数组元素归纳（或“缩减”）为单个值的函数。

			应用场景：数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据、性能优化等。

	-----------------------------------

	# 1.数据汇总 
	在处理数据集时，经常需要对数据进行汇总，比如求和、求平均值、求最大/最小值等。
	
	```js
	const numbers = [1, 2, 3, 4, 5];
	// 求和
	const total = numbers.reduce((acc, val) => acc + val, 0); 
	// 求平均值
	const average = numbers.reduce((acc, val) => acc + val, 0) / numbers.length; 
	```

	# 2.条件筛选和映射
    array.reduce(）是可以结合条件判断，用于创建一个新数组，其中只包含满足特定条件的元素。

	```js
	const users = [
		{ name: 'Alice', age: 21 },
		{ name: 'Bob', age: 25 },
		{ name: 'Charlie', age: 20 }
	];
	
	const adults = users.reduce((acc, user) => {
		if (user.age >= 18) acc.push(user);
		return acc;
	}, []);
	```

	# 3.对象属性的扁平化
    将嵌套的对象结构扁平化，便于后续处理。

	```js
	const data = {
		a: { x: 5, y: 6 },
		b: { x: 7, y: 8 }
	};
	
	const flattenedData = Object.keys(data).reduce((acc, key) => {
		acc[key] = Object.keys(data[key]).reduce((a, k) => {
			a[key + '.' + k] = data[key][k];
			return a;
		}, {});
		return acc;
	}, {});

	flattenedData ={
		'a.x': 5,
		'a.y': 6,
		'b.x': 7,
		'b.y': 8
	}
	```

	# 4、转换数据格式
    将数据从一种格式转换到另一种格式，比如将数组转换为对象。

	```js
	const arrayOfKeyValuePairs = [['key1', 'value1'], ['key2', 'value2']];
	
	const obj = arrayOfKeyValuePairs.reduce((acc, [key, value]) => {
		acc[key] = value;
		return acc;
	}, {});
	```

	# 5、聚合统计
    在处理日志数据或其他需要聚合统计的场景中，array.reduce(）可以用于计算不同分类下的统计数据。

	```js
	const salesData = [
		{ date: '2021-01-01', product: 'Apple', amount: 10 },
		{ date: '2021-01-02', product: 'Apple', amount: 5 },
		{ date: '2021-01-01', product: 'Banana', amount: 20 },
		{ date: '2021-01-01', product: 'Apple', amount: 20 },
		// ... 更多数据
	];
	
	const salesSummary = salesData.reduce((acc, sale) => {
		const key = sale.date + '-' + sale.product;
		if (!acc[key]) {
			acc[key] = { ...sale, total: 0 };
		}
		acc[key].total += sale.amount;
		return acc;
	}, {});
	
	
	// 以该数据为例，结果就会是
	{
		"2021-01-01-Apple": { date: '2021-01-01', product: 'Apple', amount: 20, total: 30 },
		"2021-01-02-Apple": { date: '2021-01-02', product: 'Apple', amount: 5, total: 5 },
		"2021-01-01-Banana": { date: '2021-01-01', product: 'Banana', amount: 20, total: 20 }
		// ... 更多数据，如果有的话
	}
	```

	# 6.在处理树状结构的数据时，array.reduce(） 可以用来递归地构建一个树形结构。

	```js
	const treeData = [
		{ id: 1, parent: null },
		{ id: 2, parent: 1 },
		{ id: 3, parent: 1 },
		{ id: 4, parent: 3 },
		{ id: 5, parent: 3 },
		{ id: 6, parent: null }, // 另一个根节点
		{ id: 7, parent: 6 },
		{ id: 8, parent: 2 },
		{ id: 9, parent: 2 },
		{ id: 10, parent: 8 }
	];

	const buildTree = (data) => {
		const tree = data.reduce((acc, item) => {
			acc[item.id] = item;
			// 判断是否存在parent节点
			if (item.parent) {
				// 如果acc[item.parent].children属性不存在，就添加一个[]值
				acc[item.parent].children = acc[item.parent].children || [];
				// 将子节点添加到父节点中
				acc[item.parent].children.push(acc[item.id]);
			}
			return acc;
		}, {});

		return Object.values(tree).filter((node) => node.parent === null);
	};


	const tree = buildTree(treeData);

	// 执行完之后，tree的值为：
	const tree = 
	[
		{
			id: 1,
			parent: null,
			children: [
				{ id: 2, parent: 1, children: [{ id: 8, parent: 2, children: [] }, { id: 9, parent: 2, children: [] }] },
				{ id: 3, parent: 1, children: [{ id: 4, parent: 3, children: [] }, { id: 5, parent: 3, children: [] }] }
			]
		},
		{
			id: 6,
			parent: null,
			children: [{ id: 7, parent: 6, children: [] }]
		}
	]
	```

	# 7、性能优化
	在某些情况下，array.reduce(）可以用于优化性能，因为它允许在单一的遍历中完成复杂的操作，减少了迭代次数。

	```
	// 假设有一个大型数组，需要执行一个复杂的操作
	const largeArray = [...] ;
	const result = largeArray.reduce((accumulator, item) => {
		// 执行复杂操作并更新accumulator
		return accumulator;
	}, initialValue);
	```

	---------------------------

	# 二、总结
	array.reduce(）可以用来数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据、性能优化等，
	使用难度相对高一些，但是能大大减少代码量。


	*/

	/*
	b=0
	b++   b++返回的是没加之前的值0，但是b确实加了1
	------- b目前是1

	++b   ++b返回的是加1后的值2，并且b也加了1
	------ b目前是2
	*/
	const checkedCount = list.reduce((total, item, index) => {
		return !item.hide && item.checked ? ++total : total
	}, 0)
	/*
	函数的是使用
	onChange={() => handelClick(maxLimit, item.checked, item.onChange)}
	*/
	const handelClick = (maxLimit: number | undefined, isChecked: number, callBack: (val: 0 | 1) => void) => {
		if (maxLimit && checkedCount >= maxLimit && !isChecked) {
			Alert(t('最多选{{num}}项！', { num: maxLimit }))
		} else {
			callBack(!isChecked ? 1 : 0)
		}
	}
	/*
	恢复默认值 
	defaultValue 默认选中数据的key组成的是数组

	list的数据
	const commonSettings = [
		{
			text: t('邀请终端'),
			value: 'mt_add',
			checked: configInfo.mt_add,
			onChange: (val: 0 | 1) => {
				propsChange({ type: 'setMtAdd', payLoad: val })
			},
		},
		{
			text: t('呼叫全部离线'),
			value: 'mt_add_all',
			checked: configInfo.mt_add_all,
			onChange: (val: 0 | 1) => {
				propsChange({ type: 'setMtAddAll', payLoad: val })
			},
		}
		...
	]
	*/
	const restoreDefaults = () => {
		if (!defaultValue) return
		list.forEach((listItem) => {
			let isDefault = false
			defaultValue.forEach((item) => {
				if (listItem.value === item) {
					isDefault = true
				}
			})
			//修改数据
			listItem.onChange(isDefault ? 1 : 0)
		})
	}
	return (
		<StyledWrap>
			<div className="title">
				<span className="main-desc">
					{mainDesc}({t('已选{{num}}个', { num: checkedCount })})
				</span>
				<span className="sub-desc">{subDesc}</span>
			</div>
			<div className="options">
				{list.map((item, index) => {
					return item.hide ? (
						<React.Fragment key={index}></React.Fragment>
					) : (
						<CheckBox
							key={index}
							checked={Boolean(item.checked)}
							onChange={() => handelClick(maxLimit, item.checked, item.onChange)}
							width={item.width ?? 178}
							height={37}
							disabled={item.disabled ?? false}
						>
							{item.text}
						</CheckBox>
					)
				})}
			</div>
			<Button onClick={restoreDefaults}>{t('恢复默认值')}</Button>
		</StyledWrap>
	)
}
